home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) Silicon Graphics, Inc. 1996 */
-
- /*
- * superfly.c
- * This program allows the user to "fly" through a simple virtual world.
- *
- * Sample solution for opengl2 labs.
- * Your challenge - make an even cooler fly!
- *
- * Utility routines are located in flyutil.c
- *
- * MODIFYING THE PROGRAM
- * ---------------------
- * New shapes should be added to the world in the routine
- * drawShapes().
- *
- * If new shapes are to be on the path of the autopilot,
- * they must be near a circle centered at the world
- * origin with a radius of 10.0, parallel to and
- * raised above the 'floor,' the X-Z plane.
- *
- * As a starting point, here are some good places to center your
- * objects:
- * ( 0.0, 1.0, 10.0 )
- * ( 7.0, 1.0, 7.0 )
- * ( 10.0, 1.0, 0.0 )
- * ( 7.0, 1.0, -7.0 )
- * ( 0.0, 1.0, -10.0 )
- * ( -7.0, 1.0, -7.0 )
- * ( -10.0, 1.0, 0.0 )
- * ( -7.0, 1.0, 7.0 )
- *
- * Copyright 1991, 1992, 1993, 1994, 1995, 1996, Silicon Graphics, Inc.
- * Technical Education Development
- */
-
-
- /* fly.h contains function prototypes, and defines constants */
- #include <GL/gl.h>
- #include <GL/glu.h>
- #include <GL/glut.h>
-
- #include "fly.h"
- #include "rgbImageFile.h"
-
- /* function prototypes for functions added to original fly.c */
- GLvoid toggleRaster( GLvoid );
- GLvoid toggleTexture( GLvoid );
- GLvoid startPicking( int x, int y );
- GLvoid printHits (GLint hits, GLint, GLint, GLuint buffer[] );
- GLvoid cullingHits (GLint hits, GLuint buffer[] );
- GLvoid cullShapes( GLvoid );
- GLvoid drawSmallWorld( GLvoid );
- GLvoid toggleCulling( GLvoid );
- GLvoid cycleFog( GLvoid );
- GLvoid toggleMovingClip( GLvoid );
- GLvoid toggleMultisampling( GLvoid );
- GLvoid togglePolygonOffset( GLvoid );
- GLvoid toggleWaving( GLvoid );
- GLint initTexgenList( char *imageFileName );
- GLint initMipmapList( GLvoid );
- GLvoid initFlag( GLvoid );
- GLvoid drawFlag( GLvoid );
- GLvoid incDensity( GLvoid );
- GLvoid decDensity( GLvoid );
- GLvoid resetEye( GLvoid );
- GLuint nearestPower(GLuint value);
-
- /* Global Variables */
-
- static enum shapes { FLOOR, TETRA, CUBE, OCTA, DODECA, ICOSA, CONE, FLAG,
- CYLINDER, SPHERE, TORUS, QUAD, FONT };
- static enum drawModes { WIREFRAME, SOLID, SIMPLE };
-
- enum drawStyles { LIT_SMOOTH, LIT_FLAT, WIRE };
- enum clipModes { OFF, ATTACH_EYE, FIXED_IN_SCENE, MOVING };
-
- static GLboolean pickedFlag[ TORUS + 1 ] = { GL_FALSE };
- static GLboolean visibleFlag[ TORUS + 1 ] = { GL_FALSE };
- static char *shapeNames[] = { "floor", "tetra", "cube", "octa", "dodeca",
- "icosa", "cone", "flag", "cylinder", "sphere",
- "torus", "quad", "font" };
-
- static GLdouble depthNormalizeFactor;
- static GLdouble modelview[16], projection[16];
- static GLint viewport[4];
-
- static GLint texgenList;
- static GLint mipmapList;
-
- extern GLboolean debugFlag; /* print eye position info? */
- extern GLboolean lighting;
- extern GLboolean showGridFlag;
- extern GLboolean blendFlag;
-
- static GLboolean clipMode = OFF;
-
- extern GLint drawStyle;
- extern GLfloat ex, ey, ez; /* eye position */
- extern GLfloat yaw; /* eye rotation about y axis in degrees */
- extern GLfloat pitch; /* eye rotation about x axis in degrees */
- extern GLfloat velocity; /* eye velocity */
-
- extern GLdouble znear, zfar; /* z distance to near and far planes */
-
- static unsigned int *image;
- static int imageWidth, imageHeight;
-
- static GLboolean picking = GL_FALSE;
- static GLboolean culling = GL_FALSE;
- static GLboolean cullingFlag = GL_FALSE; /* in culling mode? */
- static GLboolean calledRecursively = GL_FALSE;
- static GLboolean multisampleFlag = GL_FALSE;
- static GLboolean multisample_supported = GL_TRUE;
- static GLboolean polygonOffsetFlag = GL_FALSE;
- static GLboolean rasterFlag = GL_FALSE;
- static GLboolean textureFlag = GL_FALSE;
- static GLboolean waveFlag = GL_FALSE;
- static GLfloat fogDensity = 0.05;
-
- static GLfloat offsetscale = 0.5;
- static GLfloat offsetbias = 0.002;
-
- static GLfloat ctlpoints[4][4][3];
-
- #define BUFSIZE 1024
-
- static GLuint outlineFont, filledFont;
-
- #define STRING1 "Welcome to OpenGL"
- #define STRING2 "Programming 2!"
-
- #define TEXFILE1 "tex1.rgb"
- #define TEXFILE2 "tex2.rgb"
-
- GLvoid
- main( int argc, char *argv[] )
- {
- GLdouble aspect;
- GLsizei width, height;
-
- glutInit( &argc, argv );
-
- width = glutGet(GLUT_SCREEN_WIDTH);
- height = glutGet(GLUT_SCREEN_HEIGHT);
- glutInitWindowPosition( width / 4, height / 4 );
- glutInitWindowSize( width / 2, height / 2 );
- #ifdef GL_SGIS_multisample
- glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE );
- #else
- glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
- #endif
- glutCreateWindow( argv[0] );
-
- initgfx();
-
- glutIdleFunc( animate );
- glutVisibilityFunc( visibility );
- glutKeyboardFunc( keyboard );
- glutSpecialFunc( specialkeys );
- glutMouseFunc( mouse );
- glutMotionFunc( motion );
- glutReshapeFunc( reshape );
- glutDisplayFunc( drawScene );
-
- printHelp( argv[0] );
-
- glutMainLoop();
- }
-
- GLvoid
- printHelp( char *progname )
- {
-
- fprintf(stdout, "\n%s - fly through a simple virtual world.\n",
- progname );
-
- printControls();
- }
-
- GLvoid
- printControls( GLvoid )
- {
- fprintf(stdout, "\n\n"
- "<?> key - help, prints this info \n"
- "<a> key - <a>utopilot start/stop \n"
- "<b> key - <b>lend, alpha blending \n"
- "<c> key - cycle <c>lipping plane modes \n"
- "<d> key - <d>ebug mode, prints coords \n"
- "<f> key - cycle <f>og modes\n"
- "<g> key - show floor <g>rid \n"
- "<i> key - <i>mage, displays raster image \n"
- "<m> key - <m>ultisampling toggle \n"
- "<n> key - <n>ormals drawing toggle \n"
- "<p> key - <p>olygon offset toggle \n"
- "<r> key - <r>eset eye position \n"
- "<s> key - <s>election culling \n"
- "<t> key - <t>exture mapping toggle \n"
- "<w> key - <w>aving flag toggle \n"
- "SPACE key - cycle wireframe/flat shaded/smooth \n"
- "LEFT Mouse - control moving the eye forward \n"
- "MIDDLE Mouse - control moving the eye backward \n"
- "Mouse pointer - change direction: pull back to go up, forward to dive\n"
- "RIGHT Mouse - pick a shape\n"
- "UP Arrow Key - increase the fog density\n"
- "DOWN Arrow Key - decrease the fog density\n"
- "Escape key - exit the program \n" );
- }
-
- /* Initialize material property, light source, and lighting model,
- */
- GLvoid
- initLighting( GLvoid )
- {
- /* mat_specular and mat_shininess are NOT default values */
- GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
- GLfloat mat_shininess[] = { 10.0 };
-
- /* light_position is NOT default value */
- GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
-
- glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
-
- glLightfv(GL_LIGHT0, GL_POSITION, light_position);
-
- glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, 1.0);
-
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- }
-
- /* Initializes the control points for the flag.
- */
- GLvoid
- initFlag(void)
- {
- int s, t;
- static GLdouble angle = 0.0;
-
- for (s = 0; s < 4; s++)
- {
- for (t = 0; t < 4; t++)
- {
- ctlpoints[s][t][0] = (double)s/2;
- ctlpoints[s][t][1] = (double)t/2;
- ctlpoints[s][t][2] = (double)s/2*sin(angle * (double)s);
- }
- }
-
- angle = fmodf (angle + 0.1, 360.0);
- }
-
- GLvoid
- initgfx( GLvoid )
- {
- glClearColor( 0.0, 0.0, 0.0, 1.0 );
- glClearDepth( 1.0 );
-
- glClear( GL_COLOR_BUFFER_BIT );
- glutSwapBuffers();
-
- glEnable( GL_DEPTH_TEST );
-
- initLighting();
-
- initFlag();
-
- /* depth values in hit record are
- * multiplied by 2**32 - 1.
- */
- depthNormalizeFactor = pow(2, 32) - 1;
-
- resetEye();
-
- image = rgbReadImageFile("maxHeadroom.rgb", &imageWidth, &imageHeight);
-
- fprintf( stdout, "\nLoading textures\n");
- texgenList = initTexgenList( "flowers.rgb" );
- mipmapList = initMipmapList();
-
- outlineFont = createOutlineFont();
- filledFont = createFilledFont();
-
- if (!glutExtensionSupported("GL_EXT_polygon_offset")) {
- printf( "GL_EXT_polygon_offset not supported by server\n");
- }
- #ifdef GL_EXT_polygon_offset
- glPolygonOffsetEXT( offsetscale, offsetbias );
- #endif
-
- if ( !glutExtensionSupported("GL_SGIS_multisample") ) {
- printf( "GL_SGIS_multisample not supported by server\n");
- multisample_supported = GL_FALSE;
- }
-
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
- }
-
- GLvoid
- animate( GLvoid )
- {
- if (!picking)
- moveEye();
-
- /* Tell GLUT to redraw the scene */
- glutPostRedisplay();
- }
-
- GLvoid
- visibility( int state )
- {
- if (state == GLUT_VISIBLE) {
- glutIdleFunc( animate );
- } else {
- glutIdleFunc( NULL );
- }
- }
-
- /* Initialize the various input functions */
- GLvoid
- keyboard( GLubyte key, GLint x, GLint y )
- {
- /* all of the following routines are in flyutil.c */
- switch (key) {
- case ' ':
- setDrawStyle();
- break;
- case 'a':
- setAutopilot();
- break;
- case 'b':
- toggleBlend();
- break;
- case 'd':
- setDebug();
- break;
- case 'g':
- toggleShowGrid();
- break;
- case 'n':
- toggleDrawNormals();
- break;
- case 'r':
- resetEye();
- break;
- case '?':
- case '/':
- printControls();
- break;
- /* new input functions */
- case 'c':
- toggleMovingClip();
- break;
- case 'f':
- cycleFog();
- break;
- case 'i':
- toggleRaster();
- break;
- case 'm':
- toggleMultisampling();
- break;
- case 'p':
- togglePolygonOffset();
- break;
- case 's':
- toggleCulling();
- break;
- case 't':
- toggleTexture();
- break;
- case 'w':
- toggleWaving();
- break;
- case KEY_ESC:
- exit(0);
- }
-
- glutPostRedisplay();
- }
-
- GLvoid
- specialkeys( GLint key, GLint x, GLint y )
- {
- switch (key) {
- case GLUT_KEY_UP:
- incDensity();
- break;
- case GLUT_KEY_DOWN:
- decDensity();
- break;
- }
- glutPostRedisplay();
- }
-
- GLvoid
- mouse( GLint button, GLint state, GLint x, GLint y )
- {
- switch (button) {
- case GLUT_LEFT_BUTTON:
- case GLUT_MIDDLE_BUTTON:
- if (state == GLUT_DOWN)
- startMove(button, x, y);
- else
- stopMove();
- glutPostRedisplay();
- break;
-
- case GLUT_RIGHT_BUTTON:
- if (state == GLUT_DOWN)
- startPicking( x, y );
- break;
- }
- }
-
- GLvoid
- motion( GLint x, GLint y )
- {
- updatePosition( x, y );
- glutPostRedisplay();
- }
-
- GLvoid
- drawScene( GLvoid )
- {
- static GLfloat floorDiffuse[] = { 0.5, 0.5, 0.0, 1.0 };
-
- GLdouble planeABCD[4] = {0.0, -1.0, 0.0, 1.5};
- static GLfloat clipSpin = 0.0;
-
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
- glPushMatrix();
-
- if ( clipMode == ATTACH_EYE )
- {
- glClipPlane (GL_CLIP_PLANE1, planeABCD);
- }
-
- /* accomplish a viewing transformation by moving
- * the world relative to the eye
- */
- glRotatef( pitch, 1.0, 0.0, 0.0 );
- glRotatef( yaw, 0.0, 1.0, 0.0 );
- glTranslatef(-ex,-ey,-ez);
-
- if ( clipMode == FIXED_IN_SCENE )
- {
- glClipPlane (GL_CLIP_PLANE1, planeABCD);
- }
-
- else if ( clipMode == MOVING )
- {
- glPushMatrix();
- glTranslatef( 0.0, sinf( clipSpin ), 0.0 );
- glClipPlane (GL_CLIP_PLANE1, planeABCD);
- clipSpin = fmodf( clipSpin + 0.1, 2*M_PI );
- glPopMatrix();
- }
-
- if ( clipMode )
- glEnable (GL_CLIP_PLANE1);
- else
- glDisable (GL_CLIP_PLANE1);
-
- if ( rasterFlag )
- {
- static GLfloat rasterSpin = 0.0;
- glPushMatrix();
- glRotatef( -rasterSpin, 0, 1, 0 );
- glTranslatef(9.0, 1.0, 0.0);
- glRasterPos3f( 0.0, 0.0, 0.0 );
- glDrawPixels (imageWidth, imageHeight, GL_RGBA,
- GL_UNSIGNED_BYTE, image);
- glPopMatrix();
- rasterSpin = fmodf((rasterSpin + velocity*10.0), 360.0);
- }
-
- if (lighting) {
- glEnable( GL_LIGHTING );
- glEnable( GL_COLOR_MATERIAL );
- }
-
- glColor4fv( floorDiffuse );
-
- glPushMatrix();
- if (picking)
- glLoadName(FLOOR);
- else
- computeFloor(); /* function in flyutil.c */
- drawFloor();
- glPopMatrix();
-
- if ( cullingFlag && !picking && inMotion() )
- cullShapes();
-
- drawShapes();
-
- if (lighting) {
- glDisable( GL_COLOR_MATERIAL );
- glDisable( GL_LIGHTING );
- }
-
- if (picking)
- glLoadName( FONT );
-
- /* draw some 3D text */
- glPushMatrix();
- glTranslatef(-10.1, -2.5, 10.1);
- glScalef(0.1, 0.1, 0.1);
- glColor4f( 1.0, 0.7, 0.0, 1.0 );
- renderString( filledFont, STRING1 );
- glPopMatrix();
-
- glPushMatrix();
- glRotatef(90, 0, 1, 0);
- glTranslatef(-9.9, -2.5, 10.1);
- glScalef(0.1, 0.1, 0.1);
- glColor4f( 0.6, 1, 0.8, 0.6 );
- renderString( outlineFont, STRING2 );
- glPopMatrix();
- glPopMatrix();
-
- if ( !picking )
- glutSwapBuffers();
- else
- glFlush();
- checkError("drawScene");
- }
-
- GLvoid
- cullShapes( GLvoid )
- {
- GLuint selectBuf[BUFSIZE];
- GLint hits;
- register int i;
-
- culling = GL_TRUE;
-
- glSelectBuffer (BUFSIZE, selectBuf);
- (GLvoid) glRenderMode( GL_SELECT );
- glInitNames();
- glPushName( -1 );
- /* set visibleFlags for all shapes */
- for (i = 0; i < (TORUS+ 1); i++)
- visibleFlag[i] = GL_TRUE;
- drawShapes();
- hits = glRenderMode (GL_RENDER);
- cullingHits (hits, selectBuf);
- culling = GL_FALSE;
- /* Just in case cullingMode was turned off while in cullShapes,
- * if no longer in culling mode, set visibleFlags for all shapes
- */
- if (!cullingFlag)
- {
- for (i = 0; i < (TORUS+ 1); i++)
- visibleFlag[i] = GL_TRUE;
- }
- }
-
- GLvoid
- cullingHits (GLint hits, GLuint buffer[] )
- {
- register int i, j;
- int names;
- unsigned int *ptr;
-
- /* clear visibleFlags for all shapes */
- for (i = 0; i < (TORUS+ 1); i++)
- visibleFlag[i] = GL_FALSE;
-
- ptr = (unsigned int *) buffer;
- if (debugFlag)
- fprintf ( stdout, "culling hits = %d: ", hits);
- for (i = 0; i < hits; i++)
- { /* for each hit */
- names = *ptr;
- ptr += 3; /* skip z1 and z2 */
- for (j = 0; j < names; j++)
- { /* for each name */
- if (*ptr < (TORUS + 1))
- {
- if (debugFlag)
- fprintf(stdout, "%s ", shapeNames[*ptr]);
- visibleFlag[*ptr] = GL_TRUE;
- }
- ptr++;
- }
- }
- if (debugFlag)
- fprintf ( stdout, "\n\n");
- }
-
-
-
- GLvoid
- drawShapes( GLvoid )
- {
- GLfloat shapesDiffuseAlpha[] = { 0.5, 0.1, 0.8, 0.3 };
-
- glColor3f( 0.1, 0.4, 0.5 );
- drawMovedShape( TETRA, -5.0, 1.0, 8.7 );
- glColor3f( 0.2, 0.5, 0.0 );
- drawMovedShape( CUBE, -8.7, 1.0, 0.5 );
- glColor3f( 0.3, 0.6, 1.0 );
- drawMovedShape( OCTA, 5.0, 1.0, 8.7 );
- glColor3f( 0.4, 0.7, 0.0 );
- drawMovedShape( DODECA, -8.7, 1.0, -5.0 );
- glColor3f( 0.5, 0.8, 1.0 );
- drawMovedShape( ICOSA, -5.0, 1.0, -8.7 );
- glColor3f( 0.6, 0.9, 0.0 );
- drawMovedShape( CONE, 8.7, 1.0, 5.0 );
-
- /* draw a flag at the top of the cone */
- if (picking)
- glLoadName(FLAG);
-
- glColor3f( 0.6, 0.9, 1.0 );
- glPushMatrix();
- glTranslatef( 8.7,3.0,5.0 );
- drawFlag();
- glPopMatrix();
-
- glColor4fv( shapesDiffuseAlpha );
-
- if ( !culling && !calledRecursively && drawStyle != WIRE)
- {
- if ( textureFlag )
- {
- glEnable(GL_TEXTURE_2D);
- if (lighting) {
- glDisable(GL_COLOR_MATERIAL);
- glDisable(GL_LIGHTING);
- }
- glColor4f(1, 1, 1, 0.3);
-
- /* draw a textured quad using
- * explicit texture coordinates
- */
- if (picking)
- glLoadName(QUAD);
-
- glCallList(mipmapList);
- drawTexturedQuad();
-
- /* switch to automatic texture
- * coordinate generation
- */
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
-
- glCallList(texgenList);
- }
- }
-
-
- if ( blendFlag && drawStyle != WIRE )
- enableBlending();
- drawMovedShape( CYLINDER, 10.0, 1.5, 0.0 );
- drawMovedShape( SPHERE, 7.0, 2.0, -7.0 );
- drawMovedShape( TORUS, 0.0, 2.0, -10.0 );
- if ( blendFlag && drawStyle != WIRE )
- disableBlending();
-
- if ( !culling && !calledRecursively && drawStyle != WIRE)
- {
- if ( textureFlag )
- {
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- glDisable(GL_TEXTURE_2D);
- if (lighting) {
- glEnable(GL_COLOR_MATERIAL);
- glEnable(GL_LIGHTING);
- }
- }
- }
- }
-
- GLvoid
- drawMovedShape( GLint currentShape, GLfloat x, GLfloat y, GLfloat z )
- {
- if ( !visibleFlag[currentShape] && !calledRecursively )
- {
- ; /* if not visible and not called recursively, don't draw */
- }
- else
- {
- glPushMatrix();
- glTranslatef(x, y, z);
- if (culling)
- {
- drawShape( currentShape, SIMPLE );
- }
- else if ((drawStyle == WIRE || pickedFlag[currentShape] ) &&
- (!picking))
- {
- if ( pickedFlag[currentShape] && !calledRecursively )
- drawSmallWorld();
- drawShape( currentShape, WIREFRAME );
- }
- else
- {
- drawShape( currentShape, SOLID );
- }
- glPopMatrix();
- }
- }
-
- GLvoid
- drawShape( GLint currentShape, GLint drawMode )
- {
- if (picking) glLoadName(currentShape);
- switch( currentShape )
- {
- case TETRA:
- drawTetra( drawMode );
- break;
- case CUBE:
- drawCube( drawMode );
- break;
- case OCTA:
- drawOcta( drawMode );
- break;
- case DODECA:
- drawDodeca( drawMode );
- break;
- case ICOSA:
- drawIcosa( drawMode );
- break;
- case CONE:
- drawCone( drawMode );
- break;
- case CYLINDER:
- drawCylinder( drawMode );
- break;
- case SPHERE:
- drawSphere( drawMode );
- break;
- case TORUS:
- drawTorus( drawMode );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawTetra( GLint drawMode )
- {
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireTetrahedron( );
- break;
- case SOLID:
- case SIMPLE:
- glutSolidTetrahedron( );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawCube( GLint drawMode )
- {
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireCube( 1.0 );
- break;
- case SOLID:
- case SIMPLE:
- glutSolidCube( 1.0 );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawOcta( GLint drawMode )
- {
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireOctahedron( );
- break;
- case SOLID:
- case SIMPLE:
- glutSolidOctahedron( );
- break;
- default:
- break;
- }
- }
-
-
- GLvoid
- drawDodeca( GLint drawMode )
- {
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireDodecahedron( );
- break;
- case SOLID:
- case SIMPLE:
- glutSolidDodecahedron( );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawIcosa( GLint drawMode )
- {
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireIcosahedron( );
- break;
- case SOLID:
- case SIMPLE:
- glutSolidIcosahedron( );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawCone( GLint drawMode )
- {
- glRotatef(-90.0, 1.0, 0.0, 0.0);
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireCone( 1.0, 2.0, 8, 15 );
- break;
- case SOLID:
- case SIMPLE:
- glutSolidCone( 1.0, 2.0, 8, 15 );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawCylinder( GLint drawMode )
- {
- glRotatef(90.0, 1.0, 0.0, 0.0);
- switch( drawMode )
- {
- case WIREFRAME:
- WireCylinder( 1.0, 2.0 );
- break;
- case SOLID:
- case SIMPLE:
- SolidCylinder( 1.0, 2.0 );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawSphere( GLint drawMode )
- {
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireSphere( 1.0, 15, 31 );
- break;
- case SOLID:
- glutSolidSphere( 1.0, 15, 31 );
- break;
- case SIMPLE:
- glutSolidIcosahedron( );
- break;
- default:
- break;
- }
- }
-
- GLvoid
- drawTorus( GLint drawMode )
- {
- static GLint spinTorus = 0;
-
- glRotatef( (GLfloat)spinTorus, 0.0, 1.0, 0.0 );
- switch( drawMode )
- {
- case WIREFRAME:
- glutWireTorus( 0.25, 0.75, 15, 31 );
- break;
- case SOLID:
- glutSolidTorus( 0.25, 0.75, 15, 31 );
- break;
- case SIMPLE:
- SolidBox ( 2.0, 2.0, 0.5 );
- break;
- default:
- break;
- }
- if ( !picking && !culling && !calledRecursively )
- spinTorus = ( spinTorus + (int)(20*velocity) ) % 360;
- }
-
- GLvoid
- drawSmallWorld( GLvoid )
- {
- calledRecursively = GL_TRUE;
- /* need this because of the glScalef call */
- glEnable( GL_NORMALIZE );
-
- glPushMatrix();
- glScalef(0.075, 0.075, 0.075);
- drawShapes();
- glPopMatrix();
- glDisable( GL_NORMALIZE );
- calledRecursively = GL_FALSE;
- }
-
- GLvoid
- drawFloor( GLvoid )
- {
- GLfloat gridDiffuse[] = { 0.5, 0.5, 0.0, 1.0 };
- GLfloat surfaceDiffuse[] = { 0.05, 0.15, 1.0, 1.0 };
-
- #ifdef GL_EXT_polygon_offset
- if ( polygonOffsetFlag == GL_TRUE )
- glEnable(GL_POLYGON_OFFSET_EXT);
- #endif
-
- if ( drawStyle != WIRE ) {
- glColor4fv( surfaceDiffuse );
- drawFloorFilled();
- }
-
- if ( drawStyle == WIRE || showGridFlag == GL_TRUE ) {
- glColor4fv( gridDiffuse );
- drawFloorWire();
- }
-
- #ifdef GL_EXT_polygon_offset
- if ( polygonOffsetFlag == GL_TRUE )
- glDisable(GL_POLYGON_OFFSET_EXT);
- #endif
- }
-
- GLvoid
- makeFlag( GLUnurbsObj *theNurb )
- {
- GLfloat flagDiffuse[] = { 0.8, 0.8, 0.2, 1.0 };
-
- GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
- GLfloat edgePts[5][2] = /* counter clockwise */
- {{0.0, 0.0}, {1.0, 0.0}, {1.0, 1.0}, {0.0, 1.0}, {0.0, 0.0}};
-
- GLfloat curveKnots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
- /* curvePts and PwlPt are specified in a clockwise order so
- * as to cut a hole in the surface
- */
- GLfloat curvePts[4][2] = {{0.1,0.5}, {0.1,0.9}, {0.9,0.9}, {0.9,0.5}};
- GLfloat pwlPts[4][2] = {{0.9,0.5}, {0.5,0.1}, {0.1,0.5}};
-
- /* an upwards spiraling nurbs curve */
- GLfloat polePts[4][3] =
- {{0.0,0.0,0.0}, {1.0,0.25,0.0}, {-1.0,0.75,0.0}, {0.0,1.0,0.0}};
-
- glColor4fv( flagDiffuse );
-
- /* draw the flag pole */
- gluBeginCurve(theNurb);
- gluNurbsCurve (theNurb, 8, curveKnots, 3,
- &polePts[0][0], 4, GL_MAP1_VERTEX_3);
- gluEndCurve(theNurb);
-
- /* draw the flag on top of the pole */
- glPushMatrix();
- glTranslatef(0.0, 1.0, 0.0);
- gluBeginSurface(theNurb);
- gluNurbsSurface(theNurb,
- 8, knots,
- 8, knots,
- 4 * 3, 3,
- &ctlpoints[0][0][0],
- 4, 4,
- GL_MAP2_VERTEX_3);
-
- gluBeginTrim(theNurb);
- gluPwlCurve(theNurb, 5, &edgePts[0][0], 2,
- GLU_MAP1_TRIM_2);
- gluEndTrim(theNurb);
-
- gluBeginTrim(theNurb);
- gluNurbsCurve(theNurb, 8, curveKnots, 2,
- &curvePts[0][0], 4, GLU_MAP1_TRIM_2);
- gluPwlCurve(theNurb, 3, &pwlPts[0][0], 2,
- GLU_MAP1_TRIM_2);
- gluEndTrim(theNurb);
- gluEndSurface(theNurb);
- glPopMatrix();
- }
-
- /* Draw a NURBS surface with a half-oval cut out of it */
- GLvoid
- drawFlag( GLvoid )
- {
- static int first = 1;
- static GLint flagList;
- static GLUnurbsObj *theNurb = NULL;
-
- if (first) {
- GLfloat modelView[16], Projection[16];
-
- /* Save the current matrices to be loaded with the
- * display listed objects. The objects will all be
- * tessellated using these matrices.
- */
- glGetFloatv(GL_MODELVIEW_MATRIX, modelView);
- glGetFloatv(GL_PROJECTION_MATRIX, Projection);
- glGetIntegerv(GL_VIEWPORT, viewport);
-
- /* Turn off automatic loading of matrices and set up
- * sampling matrices to be used when display list is
- * created
- */
- theNurb = gluNewNurbsRenderer();
- gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 10.0);
- gluNurbsProperty(theNurb, GLU_AUTO_LOAD_MATRIX, GL_FALSE);
- gluLoadSamplingMatrices(theNurb, modelView, Projection,
- viewport);
-
- /* create display list */
- flagList = glGenLists(1);
- glNewList(flagList, GL_COMPILE_AND_EXECUTE);
- makeFlag( theNurb );
- glEndList();
- first = 0;
- } else if (waveFlag) {
- initFlag();
- makeFlag( theNurb );
- } else {
- /* if not waving and the display list exists, use it */
- glCallList( flagList );
- }
- }
-
- drawTexturedQuad( GLvoid )
- {
- float v0[3] = { -1.0, -1.0, 0.0};
- float v1[3] = {1.0, -1.0, 0.0};
- float v2[3] = {1.0, 1.0, 0.0};
- float v3[3] = { -1.0, 1.0, 0.0};
-
- float t0[3] = {0.0, 0.0};
- float t1[3] = {1.0, 0.0};
- float t2[3] = {1.0, 1.0};
- float t3[3] = {0.0, 1.0};
-
- float n0[3] = {0, 0, 1};
-
- static GLdouble angle = 0.0;
-
- glPushMatrix();
- glTranslatef(0, 3, 0);
- glRotatef(angle, 0, 1, 0);
-
- glBegin(GL_QUADS);
- glNormal3fv(n0);
- glTexCoord2fv(t0); glVertex3fv(v0);
- glTexCoord2fv(t1); glVertex3fv(v1);
- glTexCoord2fv(t2); glVertex3fv(v2);
- glTexCoord2fv(t3); glVertex3fv(v3);
- glEnd();
-
- glPopMatrix();
-
- angle = fmodf(angle + 5.0, 360.0);
- }
-
- GLvoid
- toggleRaster( GLvoid )
- {
- rasterFlag = !rasterFlag;
- }
-
- GLvoid
- toggleMultisampling( GLvoid )
- {
- if (multisample_supported) {
- #ifdef GL_SGIS_multisample
- /* Toggle polygon offset */
- multisampleFlag = !multisampleFlag;
- if ( multisampleFlag )
- glEnable( GL_MULTISAMPLE_SGIS );
- else
- glDisable( GL_MULTISAMPLE_SGIS );
- fprintf( stdout, "multisampleFlag = %d\n", multisampleFlag );
- #endif
- } else {
- printf( "GL_SGIS_multisample not supported by server\n");
- }
- }
-
- GLvoid
- togglePolygonOffset( GLvoid )
- {
- #ifdef GL_EXT_polygon_offset
- /* Toggle polygon offset */
- polygonOffsetFlag = !polygonOffsetFlag;
- #endif
- fprintf( stdout, "polygonOffsetFlag = %d\n", polygonOffsetFlag );
- }
-
- GLvoid
- toggleTexture( GLvoid )
- {
- textureFlag = !textureFlag;
- fprintf( stdout, "textureFlag = %d\n", textureFlag );
- }
-
- GLvoid
- toggleWaving( GLvoid )
- {
- waveFlag = !waveFlag;
- fprintf( stdout, "waveFlag = %d\n", waveFlag );
- }
-
- GLvoid
- cycleFog( GLvoid )
- {
- GLfloat fogColor[] = { 0.5, 0.5, 0.5, 1.0 };
- static GLint fogMode = 0;
-
- fogMode = ++fogMode % 4;
-
- switch (fogMode) {
- case 0:
- glClearColor( 0.0, 0.0, 0.0, 1.0 );
- glDisable( GL_FOG );
- break;
- case 1:
- glFogi( GL_FOG_MODE, GL_EXP2 );
- printf( "Fog mode is GL_EXP2\n" );
- break;
- case 2:
- glFogi( GL_FOG_MODE, GL_EXP );
- printf( "Fog mode is GL_EXP\n" );
- break;
- case 3:
- glFogi( GL_FOG_MODE, GL_LINEAR );
- glFogf( GL_FOG_START, 20.0 );
- glFogf( GL_FOG_END, 40.0 );
- printf( "Fog mode is GL_LINEAR: start = 20.0, end = 40.0\n" );
- break;
- }
-
- if ( fogMode != 0 )
- {
- glClearColor( fogColor[0], fogColor[1], fogColor[2],
- fogColor[3] );
- glFogfv( GL_FOG_COLOR, fogColor );
- glFogf( GL_FOG_DENSITY, fogDensity );
- glEnable( GL_FOG );
- }
-
- }
-
- GLvoid
- decDensity( GLvoid )
- {
- fogDensity -= 0.01;
- if (fogDensity < 0.0)
- fogDensity = 0.0;
-
- glFogf (GL_FOG_DENSITY, fogDensity);
- printf ("Fog density = %4.2f\n", fogDensity);
- }
-
- GLvoid
- incDensity( GLvoid )
- {
- fogDensity += 0.01;
- if (fogDensity > 1.0)
- fogDensity = 1.0;
-
- glFogf (GL_FOG_DENSITY, fogDensity);
- printf ("Fog density = %4.2f\n", fogDensity);
- }
-
- GLvoid
- toggleMovingClip( GLvoid )
- {
- /* OFF, ATTACH_EYE, FIXED_IN_SCENE, MOVING */
-
- clipMode++;
- if ( clipMode > MOVING )
- clipMode = OFF;
-
- switch( clipMode )
- {
- case OFF:
- fprintf( stdout, "clipMode = OFF\n" );
- break;
- case ATTACH_EYE:
- fprintf( stdout, "clipMode = ATTACH_EYE\n" );
- break;
- case FIXED_IN_SCENE:
- fprintf( stdout, "clipMode = FIXED_IN_SCENE\n" );
- break;
- case MOVING:
- fprintf( stdout, "clipMode = MOVING\n" );
- break;
- default:
- break;
- }
- }
-
-
- GLvoid
- toggleCulling( GLvoid )
- {
- register int i;
-
- cullingFlag = !cullingFlag;
- fprintf( stdout, "cullingFlag = %d\n", cullingFlag );
- /* set visibleFlags for all shapes */
- for (i = 0; i < (TORUS+ 1); i++)
- visibleFlag[i] = GL_TRUE;
- }
-
- GLvoid
- startPicking( GLint mouseX, GLint mouseY )
- {
- GLuint selectBuf[BUFSIZE];
- GLint hits;
- GLint viewport[4];
- GLdouble aspect;
-
- picking = GL_TRUE;
- glGetIntegerv (GL_VIEWPORT, viewport);
- glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
- glGetDoublev( GL_PROJECTION_MATRIX, projection );
- aspect = (GLdouble) viewport[2] / (GLdouble) viewport[3];
-
- glSelectBuffer (BUFSIZE, selectBuf);
- (GLvoid) glRenderMode( GL_SELECT );
- glInitNames();
- glPushName( -1 );
- glMatrixMode( GL_PROJECTION );
- glPushMatrix();
- glLoadIdentity();
- gluPickMatrix( (GLdouble) mouseX,
- (GLdouble) (viewport[3] - mouseY),
- 5, 5, /* x, y pixel tolerance for pick */
- viewport );
- gluPerspective( 45.0, aspect, znear, zfar );
- glMatrixMode( GL_MODELVIEW );
- drawScene();
- hits = glRenderMode (GL_RENDER);
- printHits (hits, mouseX, viewport[3] - mouseY, selectBuf);
- picking = GL_FALSE;
- glMatrixMode( GL_PROJECTION );
- glPopMatrix();
- glMatrixMode( GL_MODELVIEW );
- }
-
- GLvoid
- printHits (GLint hits, GLint winx, GLint winy, GLuint buffer[] )
- {
- unsigned int i, j, names, ii, jj;
- unsigned int *ptr;
- GLdouble min_depth, max_depth, objx, objy, objz;
-
- printf ("hits = %d\n", hits);
- ptr = (unsigned int *) buffer;
- for (i = 0; i < hits; i++)
- { /* for each hit */
- names = *ptr; ptr++;
-
- min_depth = ((GLdouble)(*ptr)/depthNormalizeFactor); ptr++;
- gluUnProject( winx, winy, min_depth, modelview, projection,
- viewport, &objx, &objy, &objz);
- printf( " z1 = %f", objz );
-
- max_depth = ((GLdouble)(*ptr)/depthNormalizeFactor); ptr++;
- gluUnProject( winx, winy, max_depth, modelview, projection,
- viewport, &objx, &objy, &objz);
- printf( " z2 = %f\n", objz );
-
- printf ("\tHit name:");
- for (j = 0; j < names; j++)
- { /* for each name */
- if (*ptr < (TORUS + 1))
- {
- fprintf (stdout,
- " %s", shapeNames[*ptr] );
- pickedFlag[*ptr] = !pickedFlag[*ptr];
- }
- ptr++;
- }
- printf ("\n\n");
- }
- }
-
- GLuint nearestPower(GLuint value)
- {
- int i = 1;
-
- if (value == 0)
- return - 1; /* Error! */
- for (;;)
- {
- if (value == 1)
- return i;
- else if (value == 3)
- return i *4;
- value >>= 1;
- i *= 2;
- }
- }
-
- /* Automatically build mipmaps */
-
- GLint initTexgenList( char *imageFileName )
- {
- GLuint texList;
- int texWidth, texHeight;
- GLuint *textureImage;
-
- textureImage = rgbReadImageFile(imageFileName, &texWidth, &texHeight);
-
- texList = glGenLists(1);
- glNewList(texList, GL_COMPILE);
-
- /*
- * setup environment (reflection) mapping.
- */
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
-
- /* scale texture image, make mipmaps and load texture
- * gluBuild2DMipmaps( target, components, width, height,
- * format, type, imageArray )
- */
- gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texWidth, texHeight,
- GL_RGBA, GL_UNSIGNED_BYTE, textureImage);
- glEndList();
- return( texList );
- }
-
- /* Build our own mipmaps using two different textures;
- * This function only works correctly if the two
- * images are the same size.
- */
- GLint initMipmapList( GLvoid )
- {
- GLuint texList;
- int texWidth, texHeight;
- GLsizei sWidth, sHeight, w, h;
- GLubyte *mipmap, *source;
- GLuint *image1, *image2;
- GLint level;
-
- image1 = rgbReadImageFile(TEXFILE1, &texWidth, &texHeight);
- image2 = rgbReadImageFile(TEXFILE2, &texWidth, &texHeight);
-
- printf("input image size: %dx%d\n", texWidth, texHeight);
-
- sWidth = nearestPower(texWidth);
- sHeight = nearestPower(texHeight);
-
- printf("scaled image size: %d %d\n", sWidth, sHeight);
-
- level = 0;
- w = sWidth;
- h = sHeight;
-
- texList = glGenLists(1);
- glNewList(texList, GL_COMPILE);
-
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
- GL_NEAREST_MIPMAP_NEAREST);
- while (w >= 1)
- {
- printf("Defining mipmaps for level %d, size %dx%d\n",
- level, w, h);
-
- mipmap = (GLubyte *)malloc(w * h * 4 * sizeof(GLubyte));
- if((level%2) == 0)
- source = (GLubyte *) image1;
- else
- source = (GLubyte *) image2;
-
- gluScaleImage(GL_RGBA, texWidth, texHeight, GL_UNSIGNED_BYTE,
- source, w, h, GL_UNSIGNED_BYTE, mipmap);
-
- glTexImage2D(GL_TEXTURE_2D, level, 4, w, h, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, mipmap);
-
- w = w / 2;
- h = h / 2;
- level += 1;
- }
- glEndList();
-
- return( texList );
- }
-
- GLvoid resetEye( GLvoid )
- {
- register int i;
-
- /* set visibleFlags for all shapes */
- for (i = 0; i < (TORUS+ 1); i++)
- visibleFlag[i] = GL_TRUE;
-
- initEye();
- }
-
-